package cn.zhiwen.service;

import cn.zhiwen.entity.User;
import com.netflix.hystrix.*;
import com.netflix.hystrix.strategy.concurrency.HystrixConcurrencyStrategyDefault;
import org.springframework.web.client.RestTemplate;

/**
 * 继承HystrixCommand实现熔断
 */
public class UserCommand extends HystrixCommand<User> {
    private RestTemplate restTemplate;
    private Long id;

    public UserCommand( RestTemplate restTemplate, Long id) {

        /*
        只能通过withGroupKey设置命令组名,才能通过andCommandKey来设置命令名
         */
        super(HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey("GroupName"))
                .andCommandKey(HystrixCommandKey.Factory.asKey("CommandName"))
                .andThreadPoolKey(HystrixThreadPoolKey.Factory.asKey("ThreadPoolKey")));//实现更加细粒度的线程池划分
        this.restTemplate = restTemplate;
        this.id = id;
    }

    @Override
    protected User run() throws Exception {
        User forObject = restTemplate.getForObject("http://springClient01/user?id={1}", User.class, id);
        //刷新缓存。清理缓存中失败的user
        UserCommand.flushCache(id);
        return forObject;
    }

    /**
     * 实现服务的降级逻辑
     * @return
     */
    @Override
    protected User getFallback(){
        return new User();
    }

    /**
     * 请求开启缓存  根据getCacheKey返回值区分
     * @return
     */
    @Override
    protected  String getCacheKey(){
        return String.valueOf(id);
    }

    /**
     * 清理缓存
     * @param id
     */
    public static void flushCache(Long id){
        HystrixRequestCache.getInstance(HystrixCommandKey.Factory.asKey("CommandName"),
                HystrixConcurrencyStrategyDefault.getInstance()).clear(String.valueOf(id));
    }
}
